/**
 * Created by dell2 on 2016/10/31.
 */
var express = require('express');
var util = require('util');
var router = express.Router();
var http = require('http');
var config = require('../lib/config/config').config;
var httpRequest = require('../lib/common/httpRequest').httpRequest;
var _deepCopy = require('../lib/common/common').deepCopy;
var _req = new httpRequest();
var logger = require('../lib/log4js/log4js').logger('apiRegistryV2');
var libImageService = require('../lib/registry/imageService');
var _imgSvc = new libImageService();
var user = require('../lib/user/user.js'),
    userLib = new user() ;

/**
 *  registryV2 多了一步认证的过程，所以需要交互多次才能最终获取数据
 *  api参考：https://docker.github.io/registry/spec/api/
 */

/**
 * 镜像前缀
 */
function getPrefix( param,role,username ){
    var prefix = username;

    if (param.isMarket !== undefined && param.isMarket == 'true'){
        return "library";
    }
    if (role == global.ROLE.QAER) {
        prefix = global.ENVIRONMENT.QA;
    } else if (role == global.ROLE.OPERATOR) {
        prefix = global.ENVIRONMENT.PROD;
    }
    return prefix ;
}

/**
 * http://112.74.163.191:9000/api/listImg?isMarket=true&requestimage=kube2sky
 * {
	"num_results" : 1,
	"query" : "library/",
	"results" : [{
			"description" : null,
			"name" : "library/kube2sky",
			"isMarket" : true,
			"imgPath" : "prod.internal.naturecloud.io/library/kube2sky",
			"shortname" : "kube2sky",
			"namespace" : "library",
			"taglist" : ["1.15"]
		}
	]
}
 */
router.get('/listImg', function (req, res, next) {
    var param = req.query;
    var _username = req.username;
    var role = req.cookies.role;
    var prefix = getPrefix(param,role,_username) ;
    var requestImageName = param.requestimage;
    var isFind = false ;
    //前缀是前缀，用户名是命名空间，两个可以是不同的概念
    // _username = prefix;

    getImagesByPrefix(prefix,_username,function( data,token ) {//success callback function
        //data :list of images Array
        //原来registryV1的data {"num_results": 1, "query": "nature01/", "results": [{"description": "", "name": "nature01/docker_auth"}]}
        var _ret = {};
        if (data !== null) {
            _ret = {
                num_results:data.length ,
                query:_username+"/"
            }
            var promises = [];
            data.forEach(function (item) { //item is image name ,like "admin/busybox"
                var image = {
                    description:""
                } ;
                if (item.indexOf(prefix) == 0) {
                    //add isMarket flag
                    image["isMarket"] = (param.isMarket === 'true'?true:false);
                    image["name"] = item ;
                    if (requestImageName != undefined) {
                        var currentImageName = item.replace(prefix+'/','');
                        if (requestImageName === currentImageName){
                            promises.push(
                                new Promise(function (resolve, reject) {
                                    reqTagLst( image ,token).then(function(one){   //add get image meta info flow
                                        return _imgSvc.getImageMetaInfo(prefix, one.shortname);
                                    }).then(function(obj){//merge results
                                        image["meta"] = obj;
                                        resolve( image );
                                    }).catch(function(err){//add exception error flow
                                        reject(err);
                                    });
                                })
                            );
                            isFind = true ;
                        }else{
                            //no op
                        }
                    } else{//list all images
                        promises.push(new Promise(function (resolve, reject) {
                            reqTagLst( image ).then(function(one){//add get image meta info flow
                                return _imgSvc.getImageMetaInfo(prefix, one.shortname);
                            }).then(function(obj){ //merge results
                                image.meta = obj;
                                resolve( image);
                            }).catch(function(err){//add exception error flow
                                reject(err);
                            });
                        }));
                    }
                }else{
                    logger.info("[/listImg] no library match with "+ prefix) ;
                }
            });

            Promise.all(promises).then(function (retlst) {
                //resolve(retlst);
                var totalList = [];
                retlst.forEach(function(one){
                    totalList.push(one)
                });
                _ret.num_results = totalList.length;
                _ret.results = totalList;

                if( !isFind ){
                    logger.info("Can't find the match image ->"+ requestImageName) ;
                }
                res.send(_ret);
            }).catch(function(err){
                res.send(err);
            });

        }  else{
            res.send(_ret);
        }
        /**
         * 获取tag列表
         * _item ：
         {  "description" : "",
             "name" : "nature01/docker_auth",
             "isMarket" : false,
             "imgPath" : "prod.internal.naturecloud.io/nature01/docker_auth",
             "shortname" : "docker_auth",
             "namespace" : "nature01",
             "taglist" : ["latest"]
          }
         */
        function reqTagLst(_item,basicToken ){
            return new Promise(function (resolve, reject) {
                var _lst = [];
                _item.imgPath = config.register.interaddr + '/'+_item.name;
                _item.shortname = _item.name.replace(_username+'/','');
                _item.namespace = _username;
                getTagList( _item.name ,basicToken,_username).then( function (data ) {
                   // logger.debug("[#reqTagLst]>>>>"+JSON.stringify( data ) ) ;
                    data = data.data ;
                    if (data !== null) {
                        var jsonData = JSON.parse( data ) ; //{"name":"noone/alpine","tags":["latest"]}
                        if( jsonData && jsonData["tags"] ){
                            _lst =  parseV2Tags( jsonData["tags"]) ;
                        }
                        _item.taglist = _lst.slice().reverse();
                    };
                    resolve(_item);
                }).catch(function (err) {
                    logger.error("[#reqTagLst]Can't get tags when list images") ;
                    reject( err );
                });
            });

        }
    },function ( err ) { //failed
        logger.error("[/listImg]Can't get any images") ;
        res.status(404) ;
        res.send("Can't get any images,error:"+err );
    } ) ;
});

/**
 * 列出镜像
 * http://112.74.163.191:9000/api/listImgV2?isMarket=false
 * {
	"num_results" : 1,
	"query" : "nature01/",
	"results" : [{
			"description" : "",
			"name" : "docker_auth",
			"isMarket" : false
		}
	]
}
 */
router.get('/listImgV2', function (req, res, next) {
    var param = req.query;
    var _username = req.username;
    var role = req.cookies.role;
    var prefix = getPrefix(param,role,_username) ;
    //前缀是前缀，用户名是命名空间，两个可以是不同的概念
   // _username = prefix;

    getImagesByPrefix(prefix,_username,function( data,token ) {//成功的回调方法
        var _ret = {};
        var promises = [];
        var totalList = [] ;

        if (data !== null) {
            _ret = {
                num_results:data.length ,
                query:_username+"/"
            }

            data.forEach(function (item) { //item is image name ,like "admin/busybox"
                var image = {
                    description:""
                } ;
                if (item.indexOf(prefix) == 0) {
                    //add isMarket flag
                    image["isMarket"] = (param.isMarket === 'true'?true:false);
                    image["name"] = item.replace( prefix +'/','');

                    promises.push( getImageListWithTags( image, item , token , _username ) ) ;
                }else{
                    logger.info("[/listImgV2] no library match with "+ prefix) ;
                }
            });

            //根据镜像，查询是否有tag，否则就不显示在界面上（因为目前版本的registry未实现repository的删除）
            Promise.all(promises).then( function (bundles) { //imageList
                bundles.forEach( function ( imageInfo ){
                    //getImageListWithTags方法中无论是否有tag都返回对象，根据是否是空对象来排除没有tag的repository
                    if( imageInfo && imageInfo["name"]){
                        totalList.push( imageInfo ) ;
                    }
                } );
                totalList.reverse() ; //last the first
                _ret.num_results = totalList.length;
                _ret.results = totalList;
                res.send(_ret);
            }).catch(function ( err ) {
                logAndResponse(res,404,"Can't get any images,error:"+err ,"[/listImgV2]Can't get any images :"+JSON.stringify(err)) ;
            }) ;
        }  else{
            logAndResponse(res,null, _ret ,null) ;
        }

    },function ( err ) { //失败回调方法
        logAndResponse(res,404,"Can't get any images,error:"+err ,"[/listImgV2]Can't get any images :"+JSON.stringify(err)) ;
    } ) ;

    function logAndResponse(res,status, data,logMessage){
        if( ! res ){
            return ;
        }
        if( logMessage ){
            logger.error( logMessage ) ;
        }
        if( status ){
            res.status( status ) ;
        }
        if( data ){
            res.send( data  );
        }
    }

    function getImageListWithTags(image, imageName , token , _username ){
        return new Promise(function (resolve,reject) {
            //无论是否获取到数据都返回
            getTagList(  imageName , token , _username ).then(function (bundle) {
                var _lst = getTagListFromBundle(bundle) ;
                if( image && _lst && _lst.length > 0){
                    image["tags"] = _lst ;
                    resolve( image ) ;
                }else{
                    resolve( {} ) ;
                }
            }).catch(function () {
                logger.error() ;
                resolve( {} ) ;
            }) ;
        }) ;
    }

});

/**
 * 删除某个tag的镜像
 */
router.delete('/deleteRepo', function (req, res, next) {
    var param = req.query;
    var image = param.id ;
    var tag = param.tag ;
    var _username = req.username;

    userLib.getBasicAuthenToken( _username ).then(function (basicToken) {
        return getManifestDigestBeforeDelete( image,tag, basicToken ,_username) ;
    }).then(function ( bundle) {
        return handleDigest( image,bundle,_username ) ;
    }).then(function ( bundle) {
        res.send( handleDeleteImageResp( bundle.response)  );
    }).catch(function ( bundle) {
        logger.error("['/deleteRepo]Can't delete the image "+image ,bundle) ;
        res.send(false);
    }) ;
});

/**
 * 删除镜像(迭代删除该镜像下的所有tag)
 * 参数格式：{description: "", isMarket: false, name: "alpine"}
 *  v2步骤：
 *   1、获取镜像digest /v2/<name>/manifests/<reference>  //reference can be a tag or digest
 *   2、删除镜像 DELETE /v2/<name>/manifests/<reference>   //reference must be a digest or the delete will fail
 */
router.delete('/deleteImage',function(req, res, next){
    var _username = req.username;
    var imageInfo = req.body;
    var imageName = imageInfo.name ;
    var image = _username+"/"+imageName; // 格式如:admin/nginx

    userLib.getBasicAuthenToken( _username ).then(function (basicToken) {
        return getTagList( image , basicToken , _username );
    }).then(function ( bundle) {
        var promises = [];
        var token = bundle.basicToken ;
        var _lst = getTagListFromBundle(bundle) ;

        if( _lst && _lst.length > 0 ){
            _lst.forEach(function (tag) {
                promises.push(  getManifestDigestBeforeDelete( image,tag,token,_username)) ;
            }) ;
        }
        return Promise.all(promises);
    }).then(function ( bundles ) {
        var promises = [];
        var digests = {} ;

        if(  bundles && bundles.length > 0 ){
            bundles.forEach(function ( bundle ) {
                var dig = getDigestFromBundle(bundle) ;

                //避免重复的digest，当镜像内容相同但是tag不同的时候会出现重复
                if( !digests[dig]){
                    digests[dig] = true ;
                    promises.push( handleDigest( image,bundle,_username ) );
                }
            } ) ;
        }
        return Promise.all(promises);
    }).then(function ( bundles) {
        var size = bundles.length ;
        if( bundles &&  size > 0  ) {
            var i = 0 ;
            bundles.forEach(function ( bundle ) {
                //处理每个删除返回值
                // 最大努力删除，如果有些镜像没被删除的则不做处理
                // 让用户选择手动删除
                //TODO
                if( handleDeleteImageResp( bundle.response)){
                    i = i+1 ;
                }
            } ) ;
            if( i === size){
                res.send(true);
            }else{//貌似不会进入此分之，如果失败应该是reject，然后到catch里去了
                logger.error("Deletion occurs some exception , some of the images hasn't been deleted.") ;
                //删除镜像的过程中，发生异常，导致部分镜像未删除。
                //对于这种情况只能报异常给前段，让用户处理未删除的镜像
                res.status( 500 ) ;
                res.send(  "删除过程中发生错误，请确保镜像的有效性！" );
            }
        }else{
            res.send( false );
        }
    }).catch(function(err){
        //删除镜像的过程中，发生异常，导致部分镜像未删除。
        //对于这种情况只能报异常给前段，让用户处理未删除的镜像
        logger.error("[/deleteImage]Can't delete the images recursively "+ image ,err ) ;
        res.status( 500 ) ;
        res.send(  "删除过程中发生错误，请确保镜像的有效性！" );
    });

});
/**
 *  从返回值的response header 中获取digest
 */
function handleDigest( image,bundle,_username ){
    var token = bundle.basicToken ,
        response = bundle.response,
        digest = getDigestFromHeader(response) ;
     //logger.debug("digest==="+ digest) ;
    return deleteImageByDigest( image,digest,token,_username) ;
}

/**
 * 获取镜像的tag列表
 */
router.get('/listTag',function(req, res, next){
    var param = req.query;
    var _username = req.username;
    var _startIdx = param.imageurl.indexOf('/');
    var _endIdx = param.imageurl.lastIndexOf(':');
    var _full_name = param.imageurl.substr(_startIdx+1,_endIdx-_startIdx-1);
    var _lst = [];

    userLib.getBasicAuthenToken( _username ).then(function (basicToken) {
        /**
         * getTagList(imageName,basicToken,userName)
         *   imageName  镜像名称 noone/alpine
         *   basicToken 用户名密码base64加密
         *   userName   用户名
         */
       // logger.debug("get basic token="+basicToken) ;
        return getTagList( _full_name , basicToken , _username );
    }).then(function ( bundle) {
        var token = bundle.basicToken ;
        _lst = getTagListFromBundle(bundle) ;
        res.send(_lst);
    } ).catch(function ( err ) {
        logger.error("[/listTag] Can't list tags" , err ) ;
        res.status(404) ;
        res.send(false);
    });

});
/**
 * 将镜像push到testenv下
 * @Deprecated
 */
router.put('/pushImg2TestEnv',function(req,res,next){
    var param = req.body;
    var _testEnvTag = 'testenv';
    var _url = 'http://' + config.register.host + ':' + config.register.port + '/v1/repositories/' + _testEnvTag + '/' + param.id + '/tags/'+param.tag;
    _req._request(_url, 'PUT', {}, '"'+param.imghash+'"' , function (data, result, response) {
        if (data !== null && data.data === 'true')
            res.send(true);
        else
            res.send(false);
    });
});

/**
 * 删除对应tag的镜像（逻辑删除） Docker使用的是联合文件系统，所以各个镜像之间的依赖非常复杂，为了安全起见，没有进行物理删除
 * DELETE /v2/<name>/manifests/<reference>   //reference must be a digest or the delete will fail
 */
function deleteImageByDigest(imageName,digest,basicToken,username){
    var path = "/v2/%s/manifests/%s";
    var host = getRegistryV2Host() ;

    if( !imageName || imageName ===""
        || !basicToken || basicToken === ""
        || !digest || digest === ""){
        return null ;
    }
    var header = {
        key : "Accept" ,
        value :"application/vnd.docker.distribution.manifest.v2+json"
    }
    var url =  host +util.format(path,imageName,digest) ;
    logger.debug("delete images url :"+ url ) ;
    return authenticateAndManipulate(host,url,basicToken,username,'DELETE',header) ;
}

/**
 * 获取镜像digest，需要从response的header中去digest（The manifest identified by name and reference.
 * The contents can be used to identify and resolve resources required to run the specified image.
 * The following headers will be returned with the response ：Docker-Content-Digest : Digest of the targeted content for the request.）
 *   返回值格式见/db/template.manifests
 *   api: /v2/<name>/manifests/<reference>  //reference can be a tag or digest
 */
function getManifestDigestBeforeDelete(imageName,tag,basicToken,username){
    var header = {
        key : "Accept" ,
        value :"application/vnd.docker.distribution.manifest.v2+json"
    } //需要加这个才能获取正确的digest，见docker官网文档
    return getManifestDigest( imageName,tag,basicToken,username,header ) ;
}

function getManifestDigest(imageName,tag,basicToken,username,header){
    var path = "/v2/%s/manifests/%s";
    var host = getRegistryV2Host() ;

    if( !imageName || imageName ==="" || !basicToken || basicToken === ""  ){
        return null ;
    }
    if( !tag || tag === ""){
        tag = "latest" ;
    }
    var url = host+util.format(path,imageName,tag) ;

    return authenticateAndManipulate(host,url,basicToken,username,'GET',header) ;
}

/**
 * 通过前缀查找镜像
 */
function getImagesByPrefix(prefix,_username,success,fail){
    var _lst = [];
    prefix = prefix||_username ;

    userLib.getBasicAuthenToken( _username ).then(function (basicToken) {
        return  getAllRepositories(basicToken, _username) ;
    }).then(function ( data) {
        token = data.basicToken ;
        data = data.data ;
        var jsonData = JSON.parse( data ) ;
        var repositories = jsonData["repositories"] ;
        //filter data
        if( repositories && repositories.length > 0){
            for(var i=0;i< repositories.length;i++){
               if(  startWith(repositories[i] , prefix)  ) {
                   _lst.push( repositories[i]  ) ;
               }
            }
        }
        //logger.debug("images :"+ JSON.stringify(_lst ) ) ;
        success(_lst,token);
    } ).catch(function ( err ) {
        logger.error("[#getImagesByRepo] Can't get repositories,authenticate token may be wrong" , err ) ;
        fail(err) ;
    });
}
/**
 * 通过用户名查找镜像
 */
function getImagesByNameSpace(_username,success,fail){
    return getImagesByPrefix(null,_username,success,fail) ;
}

/**
 * 获取registryV2服务器地址
 */
function getRegistryV2Host(){
    return 'http://' + config.registerv2.host + ':' + config.registerv2.port ;
}
/**
 * TODO 改善搜索，因为这个接口搜索结果是所有的image，一旦镜像数很多，就会加重网络负担
 * /v2/_catalog?n=8&last=admin/alpine return like as below:
 * {
  "repositories": [
    "admin/alpine",
    "admin/busybox",
    "admin/nodejs-sample",
    "nature01/busybox",
    "noone/alpine"
  ]
}
 */
function getAllRepositories(basicToken,username,startRepo,size){
    var host = getRegistryV2Host() ;
    var path = "/v2/_catalog";
    var url = host + path ;

    return authenticateAndAccess(host,url,basicToken,username,null) ;
}

/**
 * 获取tag数据
 * http://112.74.163.191:5000/v2/noone/alpine/tags/list
 * {
      "name": "noone/alpine",
      "tags": [
        "latest"
      ]
    }
 */
function getTagList(imageNames,basicToken,username){
    var host = getRegistryV2Host() ;
    var path = "/v2/"+imageNames+"/tags/list" ;
    var url = host + path ;
    return authenticateAndAccess(host,url,basicToken,username,null) ;
}

function authenticateAndAccess(host,url,basicToken,username,method){
    return authenticateAndManipulate(host,url,basicToken,username,method,null) ;
}

/**
 * 认证访问 (method :GET,DELETE,PUY etc.)
 *  headers 格式：{
 *    key : "",
 *    value: ""
 *  }
 *  ps:参数太多可以考虑封装成对象
 */
function authenticateAndManipulate(host,url,basicToken,username,method,headers){
    if( !method || method === ""){
        method = 'GET' ;
    }

    return new Promise(function ( resolve,reject ) {
        //1、获取bearer
        //2、根据bearer获取bearer token
        getTokenByHttp( url, basicToken ,username ,method).then(function (data) {
            data = JSON.parse( data ) ;
            var auth = 'Bearer ' + data["token"] ;
            var header = {'Authorization': auth};
            if( headers ){
                if( util.isArray( headers ) ){
                    headers.forEach( function ( head) {
                        header[head.key ] = header.value ;
                    }) ;
                }else{
                    header[headers.key ] = headers.value ;
                }
            }
            // 实际操作请求
            _req._request( url , method , header, '', function (data, result, response) {
                if( data && response.statusCode >= 200 && response.statusCode <= 299 ){
                   // logger.debug("[#authenticateAndAccess]pass token :"+ basicToken ) ;
                    resolve( {
                        url : url,
                        data:data.data ,
                        basicToken:basicToken,
                        response:response
                    }) ;
                }else{
                    if( ! response ){  var response = { statusCode:-1 } ;}
                    logger.error("[#getTokenByHttp]Can't get right response,but get "+response.statusCode+result ) ;
                    reject(result) ;
                }
            });
        }).catch( function ( err) {
            logger.error("#getTagList:Can't get token,but get "+JSON.stringify( err) ) ;
            reject( err ) ;
        }) ;
    });
}

/**
 * 向registry发送请求（PUT、DELETE、GET等方式）
 *  获取bearer（用于认证的一些字段），还是不明白的话，
 *  参考：https://github.com/docker/distribution/blob/master/docs/spec/auth/token.md
 */
function getBearerByHttp(url,method ){
    return new Promise( function(resolve,reject){
        var header = {} ;
        if( method === "DELETE"){
            header = {
               Accept:'application/vnd.docker.distribution.manifest.v2+json'
            } ;
        }
        _req._request( url , method ,header, '', function (data, result, response) {
            var resultJson = null ;
            var authentication =null ;

            if(  result ){
                resultJson = JSON.parse( result );
                if( resultJson["errors"] && resultJson["errors"][0].code === "UNAUTHORIZED" ){
                    //authentication required
                    if( response && response.headers){
                        //Bearer realm="https://127.0.0.1:5001/auth",service="Docker registry",scope="repository:noone/alpine:pull"
                        authentication = response.headers["www-authenticate"] ;
                    }
                }
            }

            if( authentication ==null || authentication===""){
                logger.error("[#getTokenByHttp]Can't get Bearer token from registryV2.") ;
                reject({
                    message:"No authentication!!"
                }) ;
            }else{
                var authens = authentication.split(",");
                var bearer = {} ;
                for(var x in authens ){
                    var item= authens[x] ;
                    var entry = item.split("=") ;

                    if( "Bearer realm"=== entry[0] ){
                        bearer["realm"] = entry[1].replace(/\"/g,"");
                    }else{
                        bearer[ entry[0]] = entry[1].replace(/\"/g,"");
                    }
                }

                resolve( bearer ) ;
            }
        });
    }) ;
}

/**
 *  向认证服务器发送请求获取bearer token
 */
function getTokenByHttp(url, basicToken,username,method ) {
    return new Promise(function (resolve,reject) {

        //先向registry发请求，获取scope，realm、service
        getBearerByHttp(url, method).then(function ( bearer ) {
            var realm = getAuthProtocol(bearer,username) ;
            var auth = 'Basic ' + basicToken;
            var header = {'Host': bearer.realm , 'Authorization': auth};
            //auth_service 获取bearer token
            logger.debug("auth_service:"+realm ) ;
            _req._request( realm , 'GET', header, '', function (data, result, response) {

                if( data && data.statusCode === 200 ){
                    //logger.debug("....."+JSON.stringify( data.data )) ;
                    resolve( data.data) ;
                }else{
                    logger.error("[#getTokenByHttp]Can't get right response,but get "+result ) ;
                    reject(result) ;
                }
            });
        }).catch(function (err) {
            logger.error("[#getTokenByHttp]Error occured!",err);
            reject( err) ;
        }) ;
    }) ;
}
/**
 * 拼接认证url
 */
function getAuthProtocol(bearer,username){
    if( bearer){
        var url = "" ;
        var queryString = "" ;

        for( var item in bearer ){
            if("realm" === item ){
                url = bearer.realm ;
            }else{
                queryString+= "&"+item+"="+bearer[item] ;
            }
        }
        if( queryString !==""  ){
            return url+"?account="+username+ queryString ;
        }else{
            return url ;
        }
    }
    return "" ;
}

/**
 * parse tag array
 * ["latest"]
 */
function  parseV2Tags( data ) {
    var _ret = {};
    var _retList = [];
    if (data !== null) {
        //logger.debug( data + ":" + util.inspect(data, {showHidden: false, depth: null}));
        if(  Object.prototype.toString.call( data )==='[object Array]' ){
            _ret = data  ;
            _retList = _ret ;
        }else{
            _ret = JSON.parse( data );
            for(var key in _ret){
                _retList.push(key);
            }
        }
        _retList.sort().reverse();
    }
    return _retList ;
}

function getTagListFromBundle(bundle){
    var _lst = [];
    var data = bundle.data ; //tags
    var jsonData = JSON.parse( data ) ; //{"name":"noone/alpine","tags":["latest"]}

    if( jsonData && jsonData["tags"] ){
        _lst =  parseV2Tags( jsonData["tags"]) ;
    }
    return _lst;
}

function getDigestFromBundle( bundle){
    var  response = bundle.response;
    return getDigestFromHeader(response) ;
}

function getDigestFromHeader( response){
    if(response && response["statusCode"] ==200 ){
        //logger.debug("response.headers:" +response.headers) ;
        var digest =response.headers["Docker-Content-Digest"] ;
        return  digest?digest: response.headers["docker-content-digest"] ; //返回小写格式额的header了 ，然而浏览器是驼峰式
    }
    return "" ;
}
/**
 * 处理镜像删除请求返回值
 * For deletes, reference must be a digest or the delete will fail. If the image exists and has been successfully deleted,
 * the following response will be issued:
    202 Accepted
    Content-Length: None
 * If the image had already been deleted or did not exist, a 404 Not Found response will be issued instead.
 */
function handleDeleteImageResp(response) {
    if( response ){
        if(response.statusCode === 202 ){
            return true ;
        }else if( response.statusCode === 404 ){
            logger.debug("[#handleDeleteImageResp] delete failed!") ;
            return false ;
        }else{
            logger.error("[#handleDeleteImageResp]Unknow response statusCode:"+ response.statusCode) ;
        }
    }else{
        logger.error("[#handleDeleteImageResp]No response specified!") ;
    }
    return false ; //didn't delete yet
}

function startWith(str,substr){
    if( str && substr){
        if ( str.substring(0,substr.length)== substr ){
            return true ;
        }
    }
    return false ;
}
module.exports = router;